#include "dht11.h"

void DHT11_Init(void)
{
    RCC_APB2PeriphClockCmd(DHT11_CLK, ENABLE);

    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = DHT11_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(DHT11_PORT, &GPIO_InitStructure);
}

void DHT11_Start(void)
{
    DHT11_LOW;
    delay_ms(18);
    DHT11_HIGH;
    delay_us(30);
}

uint8_t DHT11_Check_Response(void)
{
    uint16_t timeout = 720;
    uint8_t response = 0;
    delay_us(40);
    if (!DHT11_READ)
    {
        delay_us(80);
        if (DHT11_READ)
        {
            response = 1;
        }
    }
    while (DHT11_READ && timeout)   timeout--;
    return response;
}

uint8_t DHT11_Read_Bit(void)
{
    uint16_t timeout = 720;
    uint8_t data = 0;
    while (!DHT11_READ && timeout)  timeout--;
    delay_us(30);
    if (DHT11_READ)
    {
        data = 1;
    }
    timeout = 720;
    while (DHT11_READ && timeout)   timeout--;
    return data;
}

uint8_t DHT11_Read_Byte(void)
{
    uint8_t i, data = 0;
    for (i = 0; i < 8; i++)
    {
        data <<= 1;
        data |= DHT11_Read_Bit();
    }
    return data;
}

uint8_t DHT11_Read_Data(uint16_t *temp, uint16_t *humi)
{
    uint8_t i, data[5];
    DHT11_Start();
    if (DHT11_Check_Response() == 1)
    {
        for (i = 0; i < 5; i++)
        {
            data[i] = DHT11_Read_Byte();
        }
        if ((data[0] + data[1] + data[2] + data[3]) == data[4])
        {
            *humi = data[0] * 100;
            *humi += data[1];
            *temp = data[2] * 100;
            *temp += data[3];
        }
        return 1;
    }
    return 0;
}
